﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using System.Xml.Linq;
using xbd.ControlLib;

namespace TaoYL.BoosterStation
{
    public partial class FrmMain : Form
    {
        #region Prop
        /// <summary>
        /// 系统配置文件路径
        /// </summary>
        private string sysInfoPath = Application.StartupPath + "\\SysInfo.ini";

        /// <summary>
        /// 系统配置文件服务
        /// </summary>
        private SystemInfoService infoService = SystemInfoService.Instance;

        /// <summary>
        /// 系统配置对象
        /// </summary>
        private SystemInfo sysInfo;//= new SystemInfo();
        /// <summary>
        /// 多线程取消令牌
        /// </summary>
        private CancellationTokenSource cts;

        private PLCDataService dataService = PLCDataService.Instance;

        private System.Windows.Forms.Timer UpdateTimer=new System.Windows.Forms.Timer();
        /// <summary>
        /// 第一次扫描标志
        /// </summary>
        public bool FirstScan { get; set; }=true;

        public MessageFiliter messageFiliter;
        /// <summary>
        /// 登录时间
        /// </summary>
        public DateTime LoginTimes = DateTime.Now;

        private HistoryDataService historyDataService = HistoryDataService.Instance;
        /// <summary>
        /// 上一次存储时间
        /// </summary>
        private DateTime lastTime = DateTime.Now;
        #endregion
        public FrmMain()
        {
            InitializeComponent();
            UpdateTimer.Interval = 1000;
            UpdateTimer.Tick += UpdateTimer_Tick;
            
            UpdateTimer.Start();
            this.FormClosing += FrmMain_FormClosing;
        }

        

        #region Method
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (new MsgBoxConfirm("退出系统", "是否确认退出系统!").ShowDialog() == DialogResult.OK)
            {
                UpdateTimer.Stop();
                cts?.Cancel(); // 取消线程
            }
            else
            {
                e.Cancel = true; // 取消关闭事件
            }

        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            this.sysInfo = infoService.SysInfo;
            if (sysInfo == null)
            {
                new MsgBoxConfirm("系统配置加载失败", "系统配置").ShowDialog();
                return;
            }

            if(sysInfo.ScreenTime>0)
            {
                messageFiliter= new MessageFiliter();
                Application.AddMessageFilter(messageFiliter);
            }

            cts = new CancellationTokenSource();
            // 启动一个新的线程来执行耗时操作
            Task.Run(new Action(() =>
            {
                PLCCommunication();
            }));


        }

        /// <summary>
        /// 多线程方法体,与PLC通讯
        /// </summary>
        private void PLCCommunication()
        {
            while (!cts.IsCancellationRequested)
            {
                // 已经连接成功了
                if (dataService.IsConnected)
                {
                   var data= dataService.ReadPlcData();

                    if (data.IsSuccess)
                    {
                        //清零错误次数
                        dataService.ErrorTimes = 0;
                        //更新
                        UpdateUIData(data.Content);
                        //逻辑

                        //存储 1秒钟 扫描周期一定小于1秒
                        int tmieSpan = (int)(DateTime.Now - lastTime).TotalSeconds;
                        if (tmieSpan==1 || tmieSpan==-59)
                        {
                            historyDataService.AddHistoryData(new HistoryData
                            {
                                InsertTime = DateTime.Now,
                                TempIn1 = data.Content.TempIn1,
                                TempIn2 = data.Content.TempIn2,
                                TempOut = data.Content.TempOut,
                                PressureTank1 = data.Content.PressureTank1,
                                PressureTank2 = data.Content.PressureTank2,
                                LevelTank1 = data.Content.LevelTank1,
                                LevelTank2 = data.Content.LevelTank2,
                                PressureTankOut = data.Content.PressureTankOut
                            });
                        }
                        lastTime = DateTime.Now;
                    }
                    else
                    {
                        //容错次数
                        dataService.ErrorTimes++;
                        if (dataService.ErrorTimes > dataService.AllowErrorTimes)
                        {
                            //断开连接
                            dataService.Disconnect();
                            dataService.IsConnected = false;
                            
                        }
                    }
                }
                //连接
                else
                {
                    //如果是第一次扫描，直接连接
                    //如果不是第一次扫描，先断开再连接

                    if (!dataService.IsFirstScan)
                    {
                        Thread.Sleep(3000);
                        dataService.Disconnect();
                    }
                    else
                    {
                        dataService.IsFirstScan = false;
                    }
                    //连接
                    var result = dataService.Connect(sysInfo);
                    dataService.IsConnected = result.IsSuccess;
                }
            }
        }
        /// <summary>
        /// UI数据更新
        /// </summary>
        /// <param name="content"></param>
        private void UpdateUIData(PlcData plcData)
        {
            if (this.InvokeRequired)
            {
                try
                {
                    this.Invoke(new Action<PlcData>(UpdateUIData), plcData);
                }
                catch (Exception)
                {
                    return;
                }
            }
            else
            {
                if (FirstScan)
                {
                    this.toggle_Pump1.Checked = plcData.InPump1State;
                    this.toggle_Pump2.Checked = plcData.InPump2State;
                    FirstScan = false;
                }

                // 左侧仪表
                this.meter_PressuerIn.Value = plcData.PressureIn;
                this.label_PressureIn.Text = plcData.PressureIn.ToString("f2") + " bar";
                this.meter_PressureOut.Value = plcData.PressureOut;
                this.label_PressureOut.Text = plcData.PressureOut.ToString("f2") + " bar";

                // 底测仪表
                this.ms_TempIn1.ParamValue = plcData.TempIn1;
                this.ms_TempIn2.ParamValue = plcData.TempIn2;
                this.ms_TempOut.ParamValue = plcData.TempOut;
                this.ms_PressureTank1.ParamValue = plcData.PressureTank1;
                this.ms_PressureTank2.ParamValue = plcData.PressureTank2;
                this.ms_PressureTankOut.ParamValue = plcData.PressureTankOut;

                // 系统状态
                this.led_RunState.State = plcData.SysRunState;
                this.led_AlarmState.State = !plcData.SysAlarmState;

                // 系统参数
                this.label_PressureTank1.Text = plcData.PressureTank1.ToString("f2");
                this.label_PressureLevel1.Text = plcData.LevelTank1.ToString("f2");
                this.label_PressureTank2.Text = plcData.PressureTank2.ToString("f2");
                this.label_PressureLevel2.Text = plcData.LevelTank2.ToString("f2");
                this.label_PressureTankOut.Text = plcData.PressureTankOut.ToString("f2");

                // 流程图数据
                this.label_TempIn1.Text = plcData.TempIn1.ToString("f2");
                this.label_TempIn2.Text = plcData.TempIn2.ToString("f2");
                this.label_TempOut.Text = plcData.TempOut.ToString("f2");
                this.pump_In1.IsRun = plcData.InPump1State;
                this.pump_In2.IsRun = plcData.InPump2State;
                this.toggle_Pump1.Checked = plcData.InPump1State;
                this.toggle_Pump2.Checked = plcData.InPump2State;
                this.valve_In.State = plcData.ValveInState;
                this.valve_Out.State = plcData.ValveOutState;
                this.motor_1.PumpState = plcData.CirclePump1State ? PumpState.运行 : PumpState.停止;
                this.motor_2.PumpState = plcData.CirclePump2State ? PumpState.运行 : PumpState.停止;
                this.label_PreTankOut.Text = plcData.PressureTankOut.ToString("f2");

                // 量程
                this.wave_Tank1.Value = Convert.ToInt32((plcData.LevelTank1 / 2.0f) * 100.0f);
                this.wave_Tank2.Value = Convert.ToInt32((plcData.LevelTank2 / 2.0f) * 100.0f);
                this.button_pump1.Text = plcData.CirclePump1State ? "停止" : "启动";
                this.button_pump2.Text = plcData.CirclePump2State ? "停止" : "启动";
            }

           
        }

        private void buttonConfigue_Click(object sender, EventArgs e)
        {
            if (Program.CurrentUser != null && Program.CurrentUser.RoleName != RoleName.操作员)
                new FormParamSet().ShowDialog();
        }

        private void button_pump1_Click(object sender, EventArgs e)
        {
            if (this.button_pump1.Text == "启动")
            {
                dataService.CirclePump1Control(true);
            }
            else
            {
                dataService.CirclePump1Control(false);
            }
        }

        private void button_pump2_Click(object sender, EventArgs e)
        {
            if (this.button_pump2.Text == "启动")
            {
                dataService.CirclePump2Control(true);
            }
            else
            {
                dataService.CirclePump2Control(false);
            }
        }

        private void toggle_Pump1_CheckedChanged(object sender, EventArgs e)
        {
            // 修改pump1状态
            bool result = dataService.InPump1Control(toggle_Pump1.Checked);

            // 操作失败，恢复状态
            if (!result)
            {
                this.toggle_Pump1.CheckedChanged -= toggle_Pump1_CheckedChanged;
                this.toggle_Pump1.Checked = !this.toggle_Pump1.Checked;
                this.toggle_Pump1.CheckedChanged += toggle_Pump1_CheckedChanged;
            }
        }

        private void toggle_Pump2_CheckedChanged(object sender, EventArgs e)
        {
            // 修改pump2状态
            bool result = dataService.InPump2Control(toggle_Pump2.Checked);

            // 操作失败，恢复状态
            if (!result)
            {
                this.toggle_Pump2.CheckedChanged -= toggle_Pump2_CheckedChanged;
                this.toggle_Pump2.Checked = !this.toggle_Pump2.Checked;
                this.toggle_Pump2.CheckedChanged += toggle_Pump2_CheckedChanged;
            }
        }

        private void btn_SysReset_Click(object sender, EventArgs e)
        {
            dataService.SysRest();
        }

        private void button_Exit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void Common_Valve_DoubleClick(object sender, EventArgs e)
        {
            if (sender is xbdValve valve)
            {
                MsgBoxValveControl msgBox = new MsgBoxValveControl(valve.Name, valve.State, dataService);
                msgBox.ShowDialog();
            }
        }

        private void UpdateTimer_Tick(object sender, EventArgs e)
        {
            
            // 更新时间
            DateTime now = DateTime.Now;
            // 创建一个指定为中文（中国）的CultureInfo对象
            CultureInfo ci = new CultureInfo("zh-CN");
            // 使用指定的CultureInfo格式化日期和时间
            string formattedDate = now.ToString("yyyy-MM-dd HH:mm:ss dddd", ci);
            this.label_nowTime.Text = formattedDate;

            // 更新PLC连接状态
            this.led_PLCState.State = dataService.IsConnected;


            if (sysInfo.ScreenTime>0)
            {
                Program.TickCount++;
                if (sysInfo.ScreenTime*1000/UpdateTimer.Interval==Program.TickCount)
                {
                    //调用Windows API 锁屏
                    LockWorkStation();
                }
                Console.WriteLine($"无操作时间计数: {Program.TickCount}");
            }

            //启用用户登录自动注销功能
            if (sysInfo.LogoffTime > 0)
            {
                if(Program.CurrentUser!=null)
                {
                   TimeSpan timeSpan= DateTime.Now - LoginTimes;

                    if (timeSpan.TotalSeconds > sysInfo.LogoffTime)
                    {
                        //注销当前用户
                        Program.CurrentUser = null;
                        this.btn_UserLogin.Text = "用户登录";
                        this.lbl_User.Text = "未登录";
                    }
                }
            }
        }

        #region 无边框拖动 

        private Point mPoint;
        private void Panel_MouseDown(object sender, MouseEventArgs e)
        {
            mPoint = new Point(e.X, e.Y);
        }

        private void Panel_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.Location = new Point(this.Location.X + e.X - mPoint.X, this.Location.Y + e.Y - mPoint.Y);
            }
        }

        #endregion

        #endregion


        #region 系统锁屏
        [DllImport("user32")]
        public static extern bool LockWorkStation();

        #endregion

        private void btn_UserLogin_Click(object sender, EventArgs e)
        {
            if (this.btn_UserLogin.Text=="用户登录")
            {
                DialogResult dialogResult = new FrmLogin().ShowDialog();
                if (dialogResult == DialogResult.OK)
                {
                    this.lbl_User.Text = Program.CurrentUser.LoginName;
                    //登录成功
                    this.btn_UserLogin.Text = "用户管理";
                    //Program.CurrentUser = new SysAdminService().QuerySysAdmins().FirstOrDefault();
                    LoginTimes = DateTime.Now;
                }
                else
                {
                    //登录失败
                    Program.CurrentUser = null;
                    this.btn_UserLogin.Text = "用户登录";
                }
            }
            else
            {
                if (Program.CurrentUser != null&&Program.CurrentUser.RoleName==RoleName.管理员)
                {
                    //用户管理
                    new FrmUserManage().ShowDialog();

                }
                else
                {
                    new MsgBoxConfirm("用户管理", "只有管理员可以操作用户管理").ShowDialog();
                }
            }


        }

        private void btn_History_Click(object sender, EventArgs e)
        {
            new FormHistory().ShowDialog();
        }

        private void btn_Report_Click(object sender, EventArgs e)
        {
            new FrmReport().ShowDialog();
        }

        private void lbl_User_Click(object sender, EventArgs e)
        {
            if(new MsgBoxConfirm("用户注销","是否确认注销用户!").ShowDialog()==DialogResult.OK)
            {
                //注销当前用户
                Program.CurrentUser = null;
                this.btn_UserLogin.Text = "用户登录";
                this.lbl_User.Text = "未登录";
            }
        }
    }

    #region 消息筛选器
    public class MessageFiliter : IMessageFilter
    {
        public bool PreFilterMessage(ref Message m)
        {
            //如果检测到鼠标键盘消息，清零计数器 
            if (m.Msg==0x0200|| m.Msg == 0x0201 || m.Msg == 0x0204 || m.Msg == 0x0207 )
            {
                Program.TickCount = 0;
            }
            return false;
        }
    }
    #endregion
}
